package evolution.tests;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertTrue;

import org.junit.Assert;
import org.junit.Test;

import evolution.problem.AbstractMinimizationProblem;
import evolution.problem.AckleyMinimization;
import evolution.problem.Camelback2DMinimization;
import evolution.problem.GriewankMinimization;
import evolution.problem.RastriginMinimization;
import evolution.problem.SchwefelMinimization;
import evolution.problem.ShubertMinimization;

public class OptimizationProblemTests {

	@Test
	public void test() {
		GriewankMinimization griewankMinimization = new GriewankMinimization();
		testProblem(griewankMinimization, 0, 0);

		RastriginMinimization rastriginMinimization = new RastriginMinimization();
		testProblem(rastriginMinimization, 0, 0);

		SchwefelMinimization schwefelMinimization = new SchwefelMinimization();
		testProblem(schwefelMinimization, 420.9687, 420.9687);

		ShubertMinimization shubertMinimization = new ShubertMinimization();
		testProblem(shubertMinimization, -1.4254417354217397, 5.482796669159354);
	}

	public void testProblem(AbstractMinimizationProblem problem, double... min) {
		assertEquals(min.length, problem.getConstraints().getDimensions());
		double minValue = problem.getValue(min);
		assertEquals(problem.getOptimumValue(), minValue, 0.001);
		assertTrue(problem.getFitnessFunction().getValue(min) > 0);
	}

	@Test
	public void testShubert() {
		ShubertMinimization shubertMinimization = new ShubertMinimization();
		shubertMinimization.getConstraints().setDimensions(3);
		double[] x = { -6.653930641863013, -7.239459202913441,
				-0.8914934124079288 };

		double value = shubertMinimization.getValue(x);
		double fitnessVal = shubertMinimization.getFitnessFunction()
				.getValue(x);
		double realValue = shubertMinimization.getFitnessFunction()
				.convertToRealValue(fitnessVal);

		assertEquals(value, realValue, 0.000000001);
	}

	@Test
	public void ackleyFunctionTest() {
		AckleyMinimization problem = new AckleyMinimization();
		double minValue = problem.getValue(new double[] { 0, 0, 0, 0, 0, 0 });
		Assert.assertEquals(problem.getOptimumValue(), minValue, 0.00001);
	}

	@Test
	public void camelbackFunctionTest() {
		Camelback2DMinimization problem = new Camelback2DMinimization();
		double minValue = problem.getValue(new double[] { 0, 0 });
		Assert.assertEquals(problem.getOptimumValue(), minValue, 0);
	}
}
